package com.ahy231.service.impl;

import com.ahy231.dto.*;
import com.ahy231.entity.*;
import com.ahy231.mapper.*;
import com.ahy231.service.*;
import com.ahy231.utils.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.*;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * @author ahy231
 * @date 2021/8/5 11:29
 * @description
 */
@Service
public class AdvertiseServiceImpl implements AdvertiseService {

    private final TransactionMapper transactionMapper;
    private final LoginMapper loginMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    public AdvertiseServiceImpl(TransactionMapper transactionMapper, LoginMapper loginMapper, RedisTemplate<String, Object> redisTemplate) {
        this.transactionMapper = transactionMapper;
        this.loginMapper = loginMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Boolean publish(Advertisement advertisement) {

        Long userId = getUserId();
        Assert.notNull(userId, "service 获取不到用户 id");

        Assert.isTrue(SecurityUtils.getSubject().hasRole(advertisement.getRole()), "用户未拥有该角色");

        Integer roleId = loginMapper.getRoleIdByRole(advertisement.getRole());
        Assert.notNull(roleId, "角色查询失败");

        return transactionMapper.insert(new Transaction(null,
                advertisement.getName(),
                advertisement.getContent(),
                roleId,
                userId,
                null,
                new Timestamp(System.currentTimeMillis()),
                null,
                1,
                BigDecimal.valueOf(Double.parseDouble(advertisement.getPrice())))) > 0;
    }

    @Override
    public PageInfo<TransactionInfo> getAdv(Integer pageNum, Integer pageSize) {
        Long userId = getUserId();
        Assert.notNull(userId, "service 获取不到用户 id");
        Assert.notNull(pageNum, "页号不能为空");
        Assert.notNull(pageSize, "页面大小不能为空");
        Page<TransactionInfo> page = PageHelper.startPage(pageNum, pageSize);
        transactionMapper.getAdv(userId);
        return PageInfo.of(page);
    }

    @Override
    public PageInfo<TransactionInfo> getAllTx(Integer pageNum, Integer pageSize) {
        Long userId = getUserId();
        Assert.notNull(userId, "service 获取不到用户 id");
        Assert.notNull(pageNum, "页号不能为空");
        Assert.notNull(pageSize, "页面大小不能为空");
        Page<TransactionInfo> page = PageHelper.startPage(pageNum, pageSize);
        transactionMapper.getAllTx(userId);
        return PageInfo.of(page);
    }

    @Override
    public Boolean accept(Long transactionId) {
        Long userId = getUserId();
        Assert.notNull(userId, "service 获取不到用户 id");
        Assert.notNull(transactionId, "交易 id 不能为空");
        Transaction transaction = transactionMapper.selectOne(new QueryWrapper<Transaction>().eq("transaction_id", transactionId).select("status", "role"));
        if (transaction.getRole().equals(3)) {
            // 工地广告
            Assert.isTrue(SecurityUtils.getSubject().hasRole("driver") || SecurityUtils.getSubject().hasRole("company"), "工地不能接工地的单");
        } else {
            // 司机或公司广告
            Assert.isTrue(SecurityUtils.getSubject().hasRole("worksite"), "司机或公司不能接司机或公司的单");
        }
        Assert.isTrue(transaction.getStatus() < 2, "交易不能被接单");
        return transactionMapper.updateById(new Transaction(transactionId, null, null, null, null, userId, null, new Timestamp(System.currentTimeMillis()), 3, null)) > 0;
    }

    @Override
    public PageInfo<TransactionInfo> getWorksiteAdv(Integer pageNum, Integer pageSize) {
        Assert.notNull(pageNum, "页号不能为空");
        Assert.notNull(pageSize, "页面大小不能为空");
        Page<TransactionInfo> page = PageHelper.startPage(pageNum, pageSize);
        Integer worksiteRoleId = (Integer) redisTemplate.opsForValue().get("worksite_role_id");
        if (worksiteRoleId == null) {
            worksiteRoleId = loginMapper.getRoleIdByRole("worksite");
            redisTemplate.opsForValue().set("worksite_role_id", worksiteRoleId);
            redisTemplate.expire("worksite_role_id", 3 * 24 * 60 * 60 * 1000, TimeUnit.MILLISECONDS);
        }
        transactionMapper.getAdvByRoleId(Collections.singletonList(worksiteRoleId));
        return PageInfo.of(page);
    }

    @Override
    public PageInfo<TransactionInfo> getTruckAdv(Integer pageNum, Integer pageSize) {
        Assert.notNull(pageNum, "页号不能为空");
        Assert.notNull(pageSize, "页面大小不能为空");
        Page<TransactionInfo> page = PageHelper.startPage(pageNum, pageSize);
        Integer driverRoleId = (Integer) redisTemplate.opsForValue().get("driver_role_id");
        Integer companyRoleId = (Integer) redisTemplate.opsForValue().get("company_role_id");
        if (driverRoleId == null) {
            driverRoleId = loginMapper.getRoleIdByRole("driver");
            redisTemplate.opsForValue().set("driver_role_id", driverRoleId);
            redisTemplate.expire("driver_role_id", 3 * 24 * 60 * 60 * 1000, TimeUnit.MILLISECONDS);
        }
        if (companyRoleId == null) {
            companyRoleId = loginMapper.getRoleIdByRole("company");
            redisTemplate.opsForValue().set("company_role_id", companyRoleId);
            redisTemplate.expire("company_role_id", 3 * 24 * 60 * 60 * 1000, TimeUnit.MILLISECONDS);
        }
        transactionMapper.getAdvByRoleId(Arrays.asList(driverRoleId, companyRoleId));
        return PageInfo.of(page);
    }

    private Long getUserId() {
        return JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
    }
}
